home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hottest 6
/
Hottest 6 (1996)(PDSoft)[!].iso
/
software
/
fredfish
/
1050.lha
/
Programs
/
Binary_dt
/
source
/
dispatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-28
|
32KB
|
1,035 lines
/*
** $PROJECT: binary.datatype
**
** $VER: dispatch.c 39.6 (28.12.94)
**
** by
**
** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
**
** (C) Copyright 1994
** All Rights Reserved !
**
** $HISTORY:
**
** 28.12.94 : 039.006 : now it's a base datatype and no async layout is needed
** 24.11.94 : 039.005 : memory handling improved, layout only performed if needed
** 18.11.94 : 039.004 : added PREFS file
** 16.11.94 : 039.003 : BDTDH_NONE now works
** 15.11.94 : 039.002 : added BDTA_BytesPerLine,BDTA_DisplayHex and BDTA_ShowASCII attrs
** 13.11.94 : 039.001 : initial
*/
/* ------------------------------- include -------------------------------- */
#include "classbase.h"
/* ------------------------------- autodoc -------------------------------- */
/*FS*/ /*"AutoDoc"*/
/*GB*** binary.datatype/binary.datatype **************************************
*
* NAME
* binary.datatype -- data type for any binary file
*
* FUNCTION
* The binary data type, a base-class of all binary data, is used to
* load any binary file and displays the contents of the file in hex
* format.
*
* PREFS
* The data type tries to load the prefs file "ENV:binary.prefs" on
* each OM_NEW method to set up the attributes !
* This prefs file has the following format :
* line = NOASCII | - set BDTA_ShowASCII to FALSE
* NOWRAP | - set BDTA_DisplayWrap to FALSE
* NONE | - set BDTA_DisplayHex to BDTDH_NONE
* BYTE | - set BDTA_DisplayHex to BDTDH_BYTE
* WORD | - set BDTA_DisplayHex to BDTDH_WORD
* LONG | - set BDTA_DisplayHex to BDTDH_LONG
* BYTES <bpl> - set BDTA_BytesPerLine to <bpl> bytes
*
* METHODS
* OM_NEW -- Create a new text object from a binary file in hex mode.
*
* OM_DISPOSE -- dispose a object
*
* OM_GET -- get a attribute of the object
*
* OM_SET -- set attributes of the object
*
* OM_UPDATE -- update some attributes of the object
*
* GM_LAYOUT -- Method to layout the hex text
*
* GM_RENDER -- draw the object
*
* DTM_WRITE -- DTWM_RAW mode is supported
*
* TAGS
* BDTA_Buffer -- (UBYTE *) pointer to the buffer, which should be
* displayed.
* Applicability is (ISG).
*
* BDTA_BufferLen -- (ULONG) length of the buffer supplied with
* BDTA_Buffer tag. This must be given if the buffer tag is
* specified.
* Applicability is (ISG).
*
* BDTA_BytesPerLine -- (UWORD) number of bytes per line.
* If BDTA_DisplayHex is BDTDH_WORD it must be a multiply of 2,
* if it is BDTDH_LONG it must be a multiply of 4 !
* Default is 32.
* Applicability is (ISGNU).
*
* BDTA_DisplayHex -- (UWORD) type of the display. The following types
* are supported : BDTDH_NONE - displays no hex values
* BDTDH_BYTE - displays each byte in hex ( 8 bit)
* BDTDH_WORD - displays each word in hex (16 bit)
* BDTDH_LONG - displays each long in hex (32 bit)
* Default is BDTDH_LONG.
* Applicability is (ISGNU).
*
* BDTA_ShowASCII -- (BOOL) display at the end of the line the
* appropriate ASCII string !
* Default is TRUE.
* Applicability is (ISGNU).
*
* BDTA_DisplayWrap -- (BOOL) the BDTA_BytesPerLine are ignored and the
* byte number is retrieved from the object width !
* Default is TRUE.
* Applicability is (ISGNU).
*
* BUGS
* At the moment proportional fonts can't be handled.
*
* SEE ALSO
* datatypesclass (where ?)
*
******************************************************************************
*
*/
/*FE*/
/* ------------------------------- defines -------------------------------- */
#define G(o) ((struct Gadget *) (o))
#define GPR(msg) ((struct gpRender *) (msg))
#define SET(msg) ((struct opSet *) (msg))
#define WRMSG(msg) ((struct dtWrite *) (msg))
/* ---------------------------- instance data ----------------------------- */
struct BinaryData
{
UBYTE *bd_Buffer;
ULONG bd_BufferLen;
UWORD bd_Flags;
UWORD bd_BytesPerLine;
UWORD bd_DisplayHex;
UWORD bd_NumGroups;
UWORD bd_LineBytes;
UWORD bd_LineBufferLen;
UBYTE *bd_LineBuffer;
ULONG bd_OldX;
ULONG bd_OldY;
/* font support */
struct TextFont *bd_Font;
struct TextAttr bd_TextAttr;
UBYTE bd_FontName[MAXFONTNAME];
UBYTE bd_Name[256];
/* list of gadget objects */
struct List bd_ObjectList;
};
#define BDF_SHOWASCII (1<<0)
#define BDF_ALLOCATED (1<<1)
#define BDF_DISPLAYWRAP (1<<2)
/* ---------------------------- constant data ----------------------------- */
const ULONG methods[] = {
OM_NEW,
OM_DISPOSE,
OM_GET,
OM_SET,
OM_UPDATE,
GM_LAYOUT,
GM_RENDER,
DTM_WRITE,
~0};
/* ------------------------------ init class ------------------------------ */
/*FS*/ /*"LibCall Class *initClass(REGA6 struct ClassBase *cb)"*/
LibCall Class *initClass(REGA6 struct ClassBase *cb)
{
Class *cl;
D(bug("init binary.datatype !\n"));
if((cl = MakeClass("binary.datatype","datatypesclass",NULL,sizeof(struct BinaryData),0)))
{
cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
cl->cl_UserData = (ULONG) cb;
AddClass(cl);
}
return(cl);
}
/*FE*/
/* -------------------------- support functions --------------------------- */
/*FS*/ ULONG notifyAttrChanges(Object * obj, void * ginfo, ULONG flags, ULONG tag1,...)
{
return(DoMethod(obj, OM_NOTIFY, &tag1, ginfo, flags));
}
/*FE*/
/*FS*/ ULONG setSuperAttrs(Class *cl,Object * obj, void *ginfo,ULONG tag1,...)
{
return(DoSuperMethod(cl,obj, OM_SET, &tag1, ginfo));
}
/*FE*/
/*FS*/ void readPrefs(struct ClassBase *cb,struct BinaryData *bd)
{
BPTR fh;
ENTERING;
if((fh = Open("ENV:binary.prefs",MODE_OLDFILE)))
{
UBYTE buf[100];
STRPTR ptr;
while((ptr = FGets(fh,buf,sizeof(buf)-1)))
{
if(!Strnicmp(ptr,"NOASCII",7))
bd->bd_Flags &= ~BDF_SHOWASCII;
else if(!Strnicmp(ptr,"NOWRAP",6))
bd->bd_Flags &= ~BDF_DISPLAYWRAP;
else if(!Strnicmp(ptr,"NONE",4))
bd->bd_DisplayHex = BDTDH_NONE;
else if(!Strnicmp(ptr,"WORD",4))
bd->bd_DisplayHex = BDTDH_WORD;
else if(!Strnicmp(ptr,"LONG",4))
bd->bd_DisplayHex = BDTDH_LONG;
else if(!Strnicmp(ptr,"BYTES",5))
{
LONG value = 32;
ptr += 5;
if(StrToLong(ptr,&value) > 0)
bd->bd_BytesPerLine = value;
} else if(!Strnicmp(ptr,"BYTE",4))
bd->bd_DisplayHex = BDTDH_BYTE;
}
Close(fh);
}
LEAVING;
}
/*FE*/
/*FS*/ void useDefaultFont(struct ClassBase *cb,struct BinaryData *bd)
{
struct TextFont *deffont;
D(bug("using default font !\n"));
#undef GfxBase
deffont = ((struct GfxBase *) cb->cb_GfxBase)->DefaultFont;
#define GfxBase cb->cb_GfxBase
bd->bd_TextAttr.ta_YSize = deffont->tf_YSize;
bd->bd_TextAttr.ta_Style = FS_NORMAL;
bd->bd_TextAttr.ta_Flags = deffont->tf_Flags;
bd->bd_TextAttr.ta_Name = bd->bd_FontName;
strcpy(bd->bd_TextAttr.ta_Name,deffont->tf_Message.mn_Node.ln_Name);
bd->bd_Font = OpenFont(&bd->bd_TextAttr);
}
/*FE*/
/* --------------------------- class dispatcher --------------------------- */
/*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
{
struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
struct BinaryData *bd;
ULONG retval = 0;
switch(msg->MethodID)
{
case OM_NEW:
{
Object *newobj;
if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
{
bd = INST_DATA(cl,newobj);
/* set default setting */
bd->bd_BytesPerLine = 32;
bd->bd_DisplayHex = BDTDH_LONG;
bd->bd_Flags = BDF_SHOWASCII | BDF_DISPLAYWRAP;
NewList(&bd->bd_ObjectList);
/* read default user settings */
readPrefs(cb,bd);
setattrs(cl,newobj,(struct opSet *) msg);
/* use default textfont */
if(!bd->bd_Font)
useDefaultFont(cb,bd);
/* if no buffer is provided , get the handle from the superclass
and load the file in the buffer */
if(!bd->bd_Buffer)
{
BPTR fh;
ULONG type;
LONG num;
if(((num = GetDTAttrs((Object *) newobj,DTA_Handle ,&fh,
DTA_SourceType ,&type,
TAG_DONE)) == 2) && fh)
{
struct FileInfoBlock *fib;
D(bug("type : %ld\n",type));
switch(type)
{
case DTST_FILE:
if((fib = AllocDosObject(DOS_FIB,NULL)))
{
if(ExamineFH(fh,fib) && fib->fib_Size > 0)
{
if((bd->bd_Buffer = AllocMem(fib->fib_Size,MEMF_ANY)))
{
bd->bd_Flags |= BDF_ALLOCATED;
bd->bd_BufferLen = fib->fib_Size;
Seek(fh,0,OFFSET_BEGINNING);
Read(fh,bd->bd_Buffer,bd->bd_BufferLen);
}
}
}
FreeDosObject(DOS_FIB,fib);
if(!NameFromFH(fh,bd->bd_Name,sizeof(bd->bd_Name)))
strcpy(bd->bd_Name,"unknown");
break;
case DTST_RAM:
strcpy(bd->bd_Name,"RAM");
break;
default:
D(bug("not supported SourceType : %ld\n",type));
}
}
}
if(bd->bd_Buffer)
{
retval = (ULONG) newobj;
((struct ExtGadget *) newobj)->MoreFlags = GMORE_SCROLLRASTER;
} else /* something was going wrong, thus dispose myself */
{
D(bug("binary.datatype error : %ld\n",IoErr()));
CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
}
}
}
break;
case OM_DISPOSE:
bd = INST_DATA(cl,obj);
if(bd->bd_Buffer && (bd->bd_Flags & BDF_ALLOCATED))
FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
if(bd->bd_LineBuffer && bd->bd_LineBufferLen)
FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
if(bd->bd_Font)
CloseFont(bd->bd_Font);
#ifdef EXPERIMENTAL
/* I don't know , how gadgets can be intergrated in a datatype ?
* If there is anybody who knows ? Let me know , please !
*/
{
APTR gadobj;
/* dispose all objects from the list c*/
gadobj = bd->bd_ObjectList.lh_Head;
while((gadobj = NextObject(&gadobj)))
{
DoMethod(gadobj,OM_REMOVE);
if(G(gadobj)->GadgetRender)
DoMethod(G(gadobj)->GadgetRender,OM_DISPOSE);
DoMethod(gadobj,OM_DISPOSE);
}
}
#endif
retval = DoSuperMethodA(cl,obj,msg);
break;
case OM_UPDATE:
case OM_SET:
if((retval = setattrs(cl,obj,(struct opSet *) msg)))
DoMethod(obj,GM_LAYOUT,((struct opSet *) msg)->ops_GInfo,TRUE);
/* Pass the attributes to the super class and force a refresh
* if we need it */
if((retval += DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
{
struct RastPort *rp;
/* Get a pointer to the rastport */
if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
{
struct gpRender gpr;
/* Force a redraw */
gpr.MethodID = GM_RENDER;
gpr.gpr_GInfo = ((struct opSet *) msg)->ops_GInfo;
gpr.gpr_RPort = rp;
gpr.gpr_Redraw = GREDRAW_UPDATE;
DoMethodA (obj, (Msg) &gpr);
/* Release the temporary rastport */
ReleaseGIRPort (rp);
}
retval = 0;
}
break;
case OM_GET:
if(!(retval = getattr(cl,obj,(struct opGet *) msg)))
retval = DoSuperMethodA(cl,obj,msg);
break;
case GM_LAYOUT:
/* Tell everyone that we are busy doing things */
notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
GA_ID, G(obj)->GadgetID,
DTA_Busy, TRUE,
TAG_DONE);
/* Let the super-class partake */
retval = DoSuperMethodA (cl, obj, msg);
retval += layout(cb, cl, obj, (struct gpLayout *) msg);
break;
/* experimental code only for my test version */
#ifdef EXPERIMENTAL
case GM_GOACTIVE:
{
struct InputEvent *event = ((struct gpInput *) msg)->gpi_IEvent;
if(event->ie_Class == IECLASS_RAWKEY)
{
D(bug("goactive->Class %08lx\n",event->ie_Class));
}
retval = DoSuperMethodA(cl,obj,msg);
break;
}
case GM_HANDLEINPUT:
{
struct InputEvent *event = ((struct gpInput *) msg)->gpi_IEvent;
switch(event->ie_Class)
{
case IECLASS_RAWKEY:
D(bug("handleinput->event->ie_Code : %02lx\n",event->ie_Code));
break;
case IECLASS_RAWMOUSE:
break;
}
retval = DoSuperMethodA(cl,obj,msg);
}
break;
#endif
case GM_RENDER:
bd = INST_DATA(cl,obj);
#ifdef EXPERIMENTAL
{
APTR gadobj;
retval = DoSuperMethodA(cl,obj,msg);
gadobj = bd->bd_ObjectList.lh_Head;
D(bug("rport : %lx\n",GPR(msg)->gpr_RPort));
D(bug("ginfo : %lx\n",GPR(msg)->gpr_GInfo));
D(bug("redraw: %ld\n",GPR(msg)->gpr_Redraw));
while((gadobj = NextObject(&gadobj)))
{
D(bug("rendering gadobj : %lx\n",gadobj));
DoMethodA(gadobj,msg);
}
}
#endif
{
struct RastPort *rp = GPR(msg)->gpr_RPort;
struct DrawInfo *dri = GPR(msg)->gpr_GInfo->gi_DrInfo;
struct Rectangle rect;
struct IBox *domain;
ULONG x,y;
ULONG ux,uy;
ULONG py,px,num,grp;
ULONG topy,topx;
LONG w,h;
LONG dx,dy,height;
LONG chrs;
STRPTR lbuf = bd->bd_LineBuffer;
STRPTR bptr;
STRPTR ptr,ptr1;
STRPTR end;
UBYTE fgpen = (dri) ? dri->dri_Pens[TEXTPEN] : 1;
UBYTE bgpen = (dri) ? dri->dri_Pens[BACKGROUNDPEN] : 0;
D(bug("draw mode : %lx\n",GPR(msg)->gpr_Redraw));
if(GetDTAttrs(obj,DTA_TopVert ,&y,
DTA_TopHoriz ,&x,
DTA_VisibleVert ,&h,
DTA_VisibleHoriz,&w,
DTA_VertUnit ,&uy,
DTA_HorizUnit ,&ux,
DTA_Domain ,&domain,
TAG_DONE) == 7 && lbuf)
{
BOOL showascii = (bd->bd_Flags & BDF_SHOWASCII) ||
(bd->bd_DisplayHex == BDTDH_NONE);
UWORD numadd = (bd->bd_BufferLen > ((1<<16) - 1)) ? 10 : 6;
topy = y;
topx = x;
height = (h-1) * uy;
rect.MinX = domain->Left;
rect.MinY = domain->Top;
rect.MaxX = domain->Left + w * ux - 1;
rect.MaxY = domain->Top + h * uy - 1;
SetFont(GPR(msg)->gpr_RPort,bd->bd_Font);
SetABPenDrMd(rp,fgpen,bgpen,JAM2);
y *= uy;
x *= ux;
dx = (x - bd->bd_OldX);
dy = (y - bd->bd_OldY);
bd->bd_OldX = x;
bd->bd_OldY = y;
if(dx > domain->Width/2 || dx <-domain->Width/2)
dx = 0;
if(dy > height/2 || dy < -height/2)
dy = 0;
py = 0;
px = 0;
if(dx || dy)
ScrollRasterBF(rp,dx,dy,
rect.MinX,rect.MinY,rect.MaxX,rect.MaxY);
D(bug("dx : %ld , dy : %ld\n",dx,dy));
if(dx == 0)
{
if(dy < 0)
height = -dy;
else if(dy > 0)
{
py = height - dy;
topy += ((domain->Height / uy) - dy/uy);
}
} else if(dx > 0)
{
px = w * ux - dx;
topx += (w - (dx/ux));
w = dx/ux;
} else
{
w = (-dx/ux);
}
num = topy * bd->bd_BytesPerLine;
ptr = &bd->bd_Buffer[num];
end = &bd->bd_Buffer[bd->bd_BufferLen];
D(bug("py : %ld , height : %ld\n",py,height));
for(; py <= height ; py += rp->TxHeight)
{
bptr = ptr;
ptr1 = lbuf;
if(numadd == 10)
sprintf(lbuf,"%08lx: ",num);
else
sprintf(lbuf,"%04lx: ",num);
ptr1 += numadd;
switch(bd->bd_DisplayHex)
{
case BDTDH_BYTE:
for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
{
sprintf(ptr1,"%02lx ",*ptr);
ptr++;
ptr1 += 3;
}
while(grp < bd->bd_NumGroups)
{
strcpy(ptr1," ");
ptr1 += 3;
ptr++;
grp++;
}
break;
case BDTDH_WORD:
for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
{
sprintf(ptr1,"%04lx ",*((UWORD *) ptr));
ptr += sizeof(UWORD);
ptr1 += 5;
}
while(grp < bd->bd_NumGroups)
{
strcpy(ptr1," ");
ptr1 += 5;
ptr += sizeof(UWORD);
grp++;
}
break;
case BDTDH_LONG:
for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
{
sprintf(ptr1,"%08lx ",*((ULONG *) ptr));
ptr += sizeof(ULONG);
ptr1 += 9;
}
while(grp < bd->bd_NumGroups)
{
strcpy(ptr1," ");
ptr1 += 9;
ptr += sizeof(ULONG);
grp++;
}
break;
default:
ptr += bd->bd_BytesPerLine;
}
/* write ASCII string */
if(showascii)
{
while(bptr < ptr && bptr < end)
{
if(*bptr < 32)
*ptr1 = '.';
else
*ptr1 = *bptr;
ptr1++;
bptr++;
}
while(bptr < ptr)
{
*ptr1++ = ' ';
bptr++;
}
}
chrs = MIN((ptr1 - lbuf) - topx,w);
if(chrs > 0)
{
Move(rp,domain->Left + px,domain->Top + py + rp->TxBaseline);
Text(rp,&lbuf[topx],chrs);
}
num += bd->bd_BytesPerLine;
}
}
}
retval = DoSuperMethodA(cl,obj,msg);
break;
case DTM_WRITE:
bd = INST_DATA(cl,obj);
switch(WRMSG(msg)->dtw_Mode)
{
case DTWM_RAW:
D(bug("dtWrite Rawmode : filehandle %lx !\n",WRMSG(msg)->dtw_FileHandle));
D(bug("attrs at : %lx\n",WRMSG(msg)->dtw_AttrList));
D({
struct TagItem *tstate = WRMSG(msg)->dtw_AttrList;
struct TagItem *tag;
while((tag = NextTagItem(&tstate)))
bug("{%08lx,%ld}\n",tag->ti_Tag,tag->ti_Data);
});
Write(WRMSG(msg)->dtw_FileHandle,bd->bd_Buffer,bd->bd_BufferLen);
retval = 1;
break;
default:
retval = DoSuperMethodA(cl,obj,msg);
}
break;
default:
retval = DoSuperMethodA(cl,obj,msg);
}
return(retval);
}
/*FE*/
/*FS*/ ULONG getattr(Class *cl,Object *obj,struct opGet *msg)
{
struct BinaryData *bd = INST_DATA(cl,obj);
ULONG *storage = msg->opg_Storage;
switch(msg->opg_AttrID)
{
case DTA_TextFont:
*storage = (ULONG) bd->bd_Font;
break;
case DTA_TextAttr:
*storage = (ULONG) &bd->bd_TextAttr;
break;
case DTA_Methods:
*storage = (ULONG) methods;
break;
case BDTA_Buffer:
*storage = (ULONG) bd->bd_Buffer;
break;
case BDTA_BufferLen:
*storage = (ULONG) bd->bd_BufferLen;
break;
case BDTA_BytesPerLine:
*storage = (ULONG) bd->bd_BytesPerLine;
break;
case BDTA_DisplayHex:
*storage = (ULONG) bd->bd_DisplayHex;
break;
case BDTA_ShowASCII:
*storage = (ULONG) ((bd->bd_Flags & BDF_SHOWASCII) == BDF_SHOWASCII);
break;
case BDTA_DisplayWrap:
*storage = (ULONG) ((bd->bd_Flags & BDF_DISPLAYWRAP) == BDF_DISPLAYWRAP);
break;
default:
return(0);
}
return(1);
}
/*FE*/
/*FS*/ ULONG setattrs(Class *cl,Object *obj,struct opSet *msg)
{
struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
struct BinaryData *bd = INST_DATA(cl,obj);
struct TagItem *tstate = msg->ops_AttrList;
struct TagItem *tag;
ULONG retval = 0;
ULONG tidata;
while((tag = NextTagItem(&tstate)))
{
tidata = tag->ti_Data;
retval++;
switch(tag->ti_Tag)
{
case DTA_TextAttr:
{
struct TextFont *font;
if((font = OpenFont((struct TextAttr *) tidata)))
{
/* only use fixed width fonts */
if(font->tf_Flags & FPF_PROPORTIONAL)
{
CloseFont(font);
useDefaultFont(cb,bd);
} else
{
bd->bd_TextAttr = *((struct TextAttr *) tidata);
bd->bd_TextAttr.ta_Name = bd->bd_FontName;
strcpy(bd->bd_FontName,((struct TextAttr *) tidata)->ta_Name);
if(bd->bd_Font)
CloseFont(bd->bd_Font);
bd->bd_Font = font;
}
} else
retval--;
}
break;
case BDTA_Buffer:
{
ULONG len = GetTagData(BDTA_BufferLen,0,msg->ops_AttrList);
if(tidata && len)
{
if((bd->bd_Buffer) && (bd->bd_Flags & BDF_ALLOCATED))
FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
bd->bd_Flags &= ~BDF_ALLOCATED;
bd->bd_Buffer = (UBYTE *) tidata;
bd->bd_BufferLen = len;
retval++;
} else
retval--;
}
break;
case BDTA_BytesPerLine:
if(tag->ti_Data != bd->bd_BytesPerLine)
bd->bd_BytesPerLine = (UWORD) tag->ti_Data;
else
retval--;
break;
case BDTA_DisplayHex:
if(tag->ti_Data != bd->bd_DisplayHex)
bd->bd_DisplayHex = (UWORD) tag->ti_Data;
else
retval--;
break;
case BDTA_ShowASCII:
if(tag->ti_Data)
bd->bd_Flags |= BDF_SHOWASCII;
else
bd->bd_Flags &= ~BDF_SHOWASCII;
break;
case BDTA_DisplayWrap:
if(tag->ti_Data)
bd->bd_Flags |= BDF_DISPLAYWRAP;
else
bd->bd_Flags &= ~BDF_DISPLAYWRAP;
break;
default:
retval--;
}
}
return(retval);
}
/*FE*/
/*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
{
struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
struct BinaryData *bd = INST_DATA(cl,obj);
/* Attributes obtained from super-class */
struct TextFont *font = bd->bd_Font;
struct IBox *domain;
ULONG retval = 0;
ENTERING;
/* Get all the attributes that we are going to need for a successful layout */
if((GetDTAttrs(obj,DTA_Domain, (ULONG) &domain,
TAG_DONE) == 1))
{
/* Lock the global object data so that nobody else can manipulate it */
ObtainSemaphore (&(si->si_Lock));
#ifdef EXPERIMENTAL
{
APTR gadobj;
/* dispose all objects from the list c*/
gadobj = bd->bd_ObjectList.lh_Head;
while((gadobj = NextObject(&gadobj)))
{
DoMethod(gadobj,OM_REMOVE);
if(G(gadobj)->GadgetRender)
DoMethod(G(gadobj)->GadgetRender,OM_DISPOSE);
DoMethod(gadobj,OM_DISPOSE);
}
{
Object *image;
if((image = NewObject(NULL,"frameiclass",IA_Left ,20 /* domain->Left + 4 */,
IA_Top ,20 /* domain->Top + 1 */,
IA_Width ,100 /* domain->Width - 8 */,
IA_Height ,10 /* font->tf_YSize + 4 */,
IA_FrameType,FRAME_BUTTON,
TAG_DONE)))
if((gadobj = NewObject(NULL,"gadgetclass",GA_Left ,20 /* domain->Left + 4 */,
GA_Top ,20 /* domain->Top + 1 */,
GA_Width ,100 /* domain->Width - 8 */,
GA_Height ,10 /* font->tf_YSize + 4 */,
GA_ID , 1,
GA_Image ,image,
TAG_DONE)))
{
DoMethod(gadobj,GM_LAYOUT,gpl->gpl_GInfo,TRUE);
DoMethod(gadobj,OM_ADDTAIL,&bd->bd_ObjectList);
} else
DoMethod(image,OM_DISPOSE);
}
}
#endif
retval = si->si_TotVert;
/* We only need to perform layout if we are doing word wrap, or this
* is the initial layout call */
if(gpl->gpl_Initial || (bd->bd_Flags & BDF_DISPLAYWRAP))
{
const UBYTE displayhexbytes[] = {0,3,5,9};
const UBYTE displayasciibytes[] = {1,1,2,4};
ULONG numgroups;
ULONG bytesperline;
ULONG lines;
ULONG displayaddr = (bd->bd_BufferLen >= (1<<16)) ? 10 : 6;
ULONG showascii;
showascii = ((bd->bd_Flags & BDF_SHOWASCII) || bd->bd_DisplayHex == BDTDH_NONE) ? 1 : 0;
numgroups =
bytesperline = bd->bd_BytesPerLine;
if(bd->bd_DisplayHex)
numgroups >>= (bd->bd_DisplayHex - 1);
/* Note this wrap function doesn't work right with proportional fonts !* */
if(bd->bd_Flags & BDF_DISPLAYWRAP)
{
ULONG chars = domain->Width / bd->bd_Font->tf_XSize;
D(bug("object width : %ld\n",domain->Width));
D(bug("font width : %ld\n",font->tf_XSize));
D(bug("chars : %ld\n",chars));
bytesperline =
numgroups = (chars - displayaddr - showascii) / (displayhexbytes[bd->bd_DisplayHex] +
((showascii) ? displayasciibytes[bd->bd_DisplayHex] : 0));
if(bd->bd_DisplayHex)
bytesperline = (numgroups) << (bd->bd_DisplayHex - 1);
}
if(bytesperline < 4)
{
bytesperline = 4;
numgroups = bytesperline / displayasciibytes[bd->bd_DisplayHex];
}
lines = (bd->bd_BufferLen / bytesperline) + ((bd->bd_BufferLen % bytesperline) ? 1 : 0) - 1;
bd->bd_LineBytes = displayaddr + numgroups * displayhexbytes[bd->bd_DisplayHex] +
((showascii) ? bytesperline : 0) + 1;
bd->bd_NumGroups = numgroups;
bd->bd_BytesPerLine = bytesperline;
if(bd->bd_LineBuffer && bd->bd_LineBytes > bd->bd_LineBufferLen)
{
FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
bd->bd_LineBuffer = NULL;
}
if(!bd->bd_LineBuffer)
{
bd->bd_LineBufferLen = bd->bd_LineBytes;
bd->bd_LineBuffer = AllocMem(bd->bd_LineBufferLen,MEMF_ANY);
}
/* Compute the lines and columns type information */
si->si_VertUnit = font->tf_YSize;
si->si_VisVert = domain->Height / si->si_VertUnit;
si->si_TotVert = lines;
si->si_HorizUnit = font->tf_XSize;
si->si_VisHoriz = domain->Width / font->tf_XSize;
si->si_TotHoriz = bd->bd_LineBytes;
/* Release the global data lock */
ReleaseSemaphore(&si->si_Lock);
retval = lines;
if(gpl->gpl_Initial)
{
struct RastPort *rp;
/* Get a pointer to the rastport */
if((rp = ObtainGIRPort (gpl->gpl_GInfo)))
{
struct gpRender gpr;
/* Force a redraw */
gpr.MethodID = GM_RENDER;
gpr.gpr_GInfo = gpl->gpl_GInfo;
gpr.gpr_RPort = rp;
gpr.gpr_Redraw = GREDRAW_REDRAW;
DoMethodA (obj, (Msg) &gpr);
/* Release the temporary rastport */
ReleaseGIRPort (rp);
}
}
}
/* Not aborted, so tell the world of our newest attributes */
notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
GA_ID, G(obj)->GadgetID,
DTA_VisibleVert, domain->Height / font->tf_YSize,
DTA_TotalVert, retval,
DTA_NominalVert, font->tf_YSize * 25,
DTA_VertUnit, font->tf_YSize,
DTA_VisibleHoriz, domain->Width / font->tf_XSize,
DTA_TotalHoriz, bd->bd_LineBytes,
DTA_NominalHoriz, font->tf_XSize * 80,
DTA_HorizUnit, font->tf_XSize,
DTA_Title, bd->bd_Name,
DTA_Busy, FALSE,
DTA_Sync, TRUE,
TAG_DONE);
}
LEAVING;
return(retval);
}
/*FE*/